/**
* This will initialise all core admin widgets in the current document.
*
* @package Scribble
*/
$(document).ready(function() {

	// Initialise all scribble UI widgets
	$('[rel=scribble-widget]').each(function(wi, wel) {
		switch($(wel).attr('scribblewidget:type')) {

			// Type: media-selector
			case 'media-selector':

				// Add a "browse" button next to the input field which will be used to
				// open the media browser in a dialog window
				var btn = $('<button class="browse" type="button" style="margin-left:5px;">Browse</button>');
				btn.data('linked-input', $(wel));
				btn.click(function() {
					Scribble.openMediaBrowser($(this).data('linked-input'));
				});
				btn.insertAfter($(wel));
				$(wel).width(250);
				break;

			// Type: model-binding
			case 'model-binding':

				// Extract config
				var configRaw = $(wel).attr('scribblewidget:config').split(',');
				var config = {}, tmp;
				for(var i=0; i<configRaw.length; i++) {
					tmp = configRaw[i].split('=');
					config[tmp[0]] = tmp[1];
				}

				// Create DOM elements
				var btn = $('<button class="browse" type="button" style="margin-left:5px;">Browse</button>');
				btn.data('linked-input', $(wel));
				btn.click(function() {
					Scribble.openModelBinder($(this).data('linked-input'), config);
				});
				btn.insertAfter($(wel));
				$(wel).width(250);
				break;

			// Type: ModelCriteria builder
			case 'model-criteria':

				// Check for widget javascript
				if(!top.ScribbleModelCriteriaWidget) {
					alert("This UI contains a 'model-privileges' widget,\nbut 'scribble-model-criteria-widget.js' has not been included.");
					break;
				}
				new ScribbleModelCriteriaWidget(wel);
				break;

			// Type: Scribble privileges setter (for use on a specific resource)
			case 'privilege-editor':

				// Check for widget javascript
				if(!top.ScribbleAuthWidget) {
					alert("This UI contains a 'scribble-privileges' widget,\nbut 'scribble-auth-widget.js' has not been included.");
					break;
				}
				new ScribbleAuthWidget($(wel));
				break;

			// Type: rte (Rich Text Editor)
			case 'rte':

				// Generate an id if one is not already defined (required by TinyMCE)
				if(!wel.id) {
					$(wel).attr('id', 'rte-'+Math.round(Math.random()*100000));
				}
		
				// Detemine which settings to use on this RTE (defined by the
				// scribblewidget:config atrtibute)
				var settingsId = $(wel).attr('scribblewidget:config');
				if(settingsId=='') {
					settingsId = 'scribbleDefaultRteConfig';
				}
				var settings = window[settingsId] ? window[settingsId] : window['scribbleDefaultRteConfig'];
				var ed = new tinymce.Editor(wel.id, settings);
				ed.render();
				break;

			// Type: schedule editor
			case 'schedule':

				// Check for widget javascript
				if(!top.ScribbleScheduleWidget) {
					alert("This UI contains a 'schedule' widget,\nbut 'scribble-schedule-widget.js' has not been included.");
					break;
				}
				new ScribbleScheduleWidget(wel);
				break;

			// Unknown widget - hopefully it's handled elsewhere!
			default:
				break;
		}
	});
});


var Scribble = {

	/**
	* Opens the media browser in a dialog box.
	*
	* @param HtmlInputElement The element that holds, or will hold, media info
	* @return void
	*/
	openMediaBrowser: function(input) {

		// Extract the list of existing selections, if any
		var data = input.val()=='' ? '[]' : input.val();

		// Create the dialog 
		var dialog = $('<div id="media-selector-dialog"></div>').dialog({

			/* Options */
			autoOpen: false,
			height: 400,
			modal: true,
			resizable: false,
			width: 700,
	
			/* Event handlers */
			dragStart: function() {
				$(this).children('iframe').hide();
			},
			dragStop: function() {
				$(this).children('iframe').show();
			}
		}).html('<iframe style="border:none;width:100%;height:350px;" src="'+Buan.UrlCommand.createUrl('scribble', 'media-library', 'browser-widget', {callback: 'xFrameCallback_mediaSelector', data: data})+'"></iframe></div>');
		dialog.data('widgetInput', input);
		dialog.dialog('open');
	},

	/**
	* Opens the model binding UI in a dialog box.
	*
	* @param HtmlInputElement The element that holds, or will hold, binding info
	* @param object The widget config object
	* @return void
	*/
	openModelBinder: function(input, config) {

		// Extract the list of existing selections, if any
		var data = input.val()=='' ? '{"models":[]}' : input.val();

		// Prepare the GET paramters to send to the widget loader
		var gParams = {
			callback: 'xFrameCallback_modelBinding',
			data: data
		};
		gParams = $.extend({}, gParams, config);

		// Create the dialog 
		var dialog = $('<div id="model-binding-dialog"></div>').dialog({

			/* Options */
			autoOpen: false,
			height: 400,
			modal: true,
			resizable: false,
			width: 700,
	
			/* Event handlers */
			dragStart: function() {
				$(this).children('iframe').hide();
			},
			dragStop: function() {
				$(this).children('iframe').show();
			}
		}).html('<iframe style="border:none;width:100%;height:350px;" src="'+Buan.UrlCommand.createUrl('scribble', 'model-binding', 'browser-widget', gParams)+'"></iframe></div>');
		dialog.data('widgetInput', input);
		dialog.dialog('open');
	}
};


/**
* The callback function used by the media-selector widget. It needs to be in the
* global scope as the function name is passed to the media browser widget via a
* URL.
*
* @param string The action being executed
* @param object Reference to the MediaBrowser object (which is defined in "browser-widget.js"
* @param mixed Data passed back from the media browser UI
* @return void
*/
function xFrameCallback_mediaSelector(action, browser, data) {
	switch(action) {
		case 'complete':
			var input = $('#media-selector-dialog').data('widgetInput');
			input.val($.toJSON(data.selection));
			$('#media-selector-dialog').dialog('close').dialog('destroy').remove();
			break;

		default:
			break;
	}
}

/**
* The callback function used by the model-binding widget. It needs to be in the
* global scope as the function name is passed to the media browser widget via a
* URL.
*
* @param string The action being executed
* @param object Reference to the ModelBinder object (which is defined in "model-binding-widget.js"
* @param mixed Data passed back from the UI
* @return void
*/
function xFrameCallback_modelBinding(action, browser, data) {
	switch(action) {
		case 'complete':
			var input = $('#model-binding-dialog').data('widgetInput');
			input.val($.toJSON(data));
			$('#model-binding-dialog').dialog('close').dialog('destroy').remove();
			break;

		default:
			break;
	}
}

/**
* The file-browser for use by TinyMCE. This opens the media browser UI.
*
* @param string
* @param string
* @param 
* @param
* @param
* @return void
*/
function mceFileBrowser(field_name, url, type, win, editor_id) {
	top.mceFileBrowser_win = win;
	tinyMCE.activeEditor.windowManager.open({
		file: Buan.UrlCommand.createUrl('scribble', 'media-library', 'browser-widget', {callback:'xFrameCallback_tinymceImage', data:'["'+url+'"]', stype:'jpg,gif,bmp,png'}),
		title: "Select a file",
		width: 700,
		height: 400,
		scrollbars: "no",
		close_previous: "no"
	});
}

/**
* The callback function used by the TinyMCE image-selector. It needs to be in the
* global scope as the function name is passed to the media browser widget via a
* URL.
*
* @param string The action being executed
* @param object Reference to the MediaBrowser object
* @param mixed Data passed back from the media browser UI
* @return void
*/
function xFrameCallback_tinymceImage(action, browser, data) {
	var opener = window.opener.mceFileBrowser_win;
	var src = opener.document.getElementById('src');
	src.value = data.selection[0];
	opener.ImageDialog.showPreviewImage(src.value);
	var desc = opener.document.getElementById('alt');
	desc.value = src.value;
	delete window.opener.mceFileBrowser_win;

	switch(action) {
		case 'complete':
			window.close();
			break;

		default:
			break;
	}
}